<template>
  <div class="menu-dashboard">
    <div
      ref="menuItemEls"
      v-for="item in options"
      :key="item.key"
      :value="item.checked"
      style="height: inherit"
    >
      <div class="menu-item" @click="linkRoute(item, $event)">
        <p>{{ item.title }}</p>
        <div class="popup">
          <div
            class="popup-item"
            @click="linkRoute(child, $event)"
            v-for="child in item.children"
            :key="child.key"
          >
            {{ child.title }}
          </div>
        </div>
      </div>
    </div>
    <div class="menu-item-line" :style="{ width: itemWidth, left: lineLeft }"></div>
  </div>
</template>

<script setup lang="ts">
export interface MenuOption {
  key: string
  title: string
  checked: boolean
  link: string
  props?: any
  children?: MenuOption[]
}

interface Props {
  modelValue: string
  options: Array<MenuOption>
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  options: () => []
})

const emit = defineEmits(['update:modelValue', 'change'])

const router = useRouter()

const lineLeft = ref('0')
const itemWidth = ref('0')
const menuItemEls = ref()

const state = ref({
  isFirstLoad: true
})

const checkMenu = (name: string, menu: Array<MenuOption>, flag = 'main') => {
  for (const item of menu) {
    item.checked = false
    if (item.link === name && flag === 'node') {
      return true
    } else if (item.link === name && flag === 'main') {
      item.checked = true
    }

    if (item.children) {
      if (checkMenu(name, item.children, 'node')) {
        item.checked = true
      }
    }
  }
  return false
}

onMounted(() => {
  const toPath = props.modelValue
  checkMenu(toPath, props.options)

  setTimeout(() => {
    calcItemWidth()
  }, 100)
})

watch(
  () => router.currentRoute.value,
  (val: any) => {
    if (!props.options.map((i) => i.link).includes(val.name)) return

    if (state.value.isFirstLoad) {
      state.value.isFirstLoad = false
      return
    }

    checkMenu(val.name, props.options)

    setTimeout(() => {
      calcItemWidth()
    }, 100)
  },
  {
    immediate: true,
    deep: true
  }
)

const linkRoute = (menu: MenuOption, e: any) => {
  e.stopPropagation()
  if (menu.props) {
    router.push({ name: menu.link, params: { ...menu.props } })
  } else {
    router.push({ name: menu.link })
  }
  emit('update:modelValue', menu.link)
  emit('change')
}

const calcItemWidth = () => {
  let isChecked = false
  let thisLineLeft = 0

  lineLeft.value = '0'

  for (const item of menuItemEls.value) {
    isChecked = JSON.parse(item.getAttribute('value'))
    if (isChecked) {
      itemWidth.value = item.clientWidth + 'px'
      break
    } else {
      thisLineLeft += item.clientWidth
    }
  }

  lineLeft.value = thisLineLeft + 'px'
}
</script>

<style scoped lang="scss">
.menu-dashboard {
  height: inherit;
  display: flex;
  position: relative;
  .menu-item {
    position: relative;
    font-size: 14px;
    color: #000;
    padding: 0 20px;
    display: flex;
    height: inherit;
    justify-content: center;
    white-space: nowrap;
    cursor: pointer;

    & > p {
      font-size: 14px;
      color: #000;
    }

    &:hover {
      .popup {
        transform: scaleY(1);
      }
    }

    .popup {
      position: absolute;
      background: #fff;
      transition: 0.3s;
      top: 64px;
      transform: scaleY(0);
      transform-origin: top;
      z-index: 99;
      border-radius: 4px;

      .popup-item {
        height: 36px;
        line-height: 36px;
        padding: 0 22px;
        font-size: 14px;
        color: #27282b;
        margin: 5px;
        transition: 0.4s;
        border-radius: 4px;

        &:hover {
          background: lighten($main-color, 25%);
        }
      }
    }
  }

  .menu-item-line {
    position: absolute;
    bottom: 0;
    height: 3px;
    background: $main-color;
    transition: 0.4s;
    border-radius: 2px;
  }
}
</style>
